package com.beemans.corekit.integration.admob;

import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.LifecycleOwner;

import com.google.android.gms.ads.AdValue;
import com.google.android.gms.ads.ResponseInfo;

public class AbNativeAdvert extends AbBaseAdvert implements AbAdNetworkListener, AbAdEventListener {
    @NonNull
    private final LifecycleOwner lifecycleOwner;
    @NonNull
    private final AbNativeAdvertConfig advertConfig;
    @Nullable
    private final FragmentActivity fragmentActivity;
    @Nullable
    private final IAbNativeSelfRender nativeSelfRender;
    @Nullable
    private AbNativeAdvertCallback advertCallback;
    @Nullable
    private ViewGroup advertContainer;
    @Nullable
    private AbNativeAdWrapper adWrapper;
    @Nullable
    private AbNativeAdWrapper realAdWrapper;

    public AbNativeAdvert(
            @NonNull LifecycleOwner lifecycleOwner,
            @NonNull AbNativeAdvertConfig advertConfig
    ) {
        this(lifecycleOwner, advertConfig, null, null);
    }

    public AbNativeAdvert(
            @NonNull LifecycleOwner lifecycleOwner,
            @NonNull AbNativeAdvertConfig advertConfig,
            @Nullable IAbNativeSelfRender nativeSelfRender,
            @Nullable AbNativeAdvertCallback advertCallback
    ) {
        this.lifecycleOwner = lifecycleOwner;
        this.advertConfig = advertConfig;
        this.advertCallback = advertCallback;
        this.nativeSelfRender = nativeSelfRender;
        this.fragmentActivity = AdvertLifeUtils.getContext(lifecycleOwner);

        if (nativeSelfRender != null) {
            this.advertContainer = nativeSelfRender.getAdContainer();
        }
        if (fragmentActivity == null) {
            return;
        }

        adWrapper = new AbNativeAdWrapper(advertConfig.getPlacementId());

        AdvertLifeUtils.launchWhenDestroy(lifecycleOwner, this::onAdvertRelease);

        if (advertCallback != null) {
            advertCallback.onAdvertStart(this);
        }
    }

    @Override
    public boolean isAdvertReady() {
        if (adWrapper != null && adWrapper.isAdvertReady()) {
            return true;
        }
        return AbAdvertManager.isNativeAdvertReady(advertConfig);
    }

    @Override
    public boolean isAdvertLoading() {
        if (adWrapper != null && adWrapper.isAdvertLoading()) {
            return true;
        }
        return AbAdvertManager.isNativeAdvertLoading(advertConfig);
    }

    @Override
    protected void loadAdvert() {
        loadAdvert(false);
    }

    @Override
    public void onAdvertRelease() {
        super.onAdvertRelease();

        if (advertCallback != null) {
            advertCallback = null;
        }
        if (advertContainer != null) {
            advertContainer.removeAllViews();
            advertContainer = null;
        }

        if (advertConfig.isShowAfterLoaded()) {
            if (adWrapper != null) {
                if (!adWrapper.isAdvertLoading()) {
                    adWrapper.destroy();
                }
                adWrapper = null;
            }
            if (realAdWrapper != null) {
                realAdWrapper.destroy();
                realAdWrapper = null;
            }
        }
    }

    /**
     * @noinspection unused, SameParameterValue
     */
    private void loadAdvert(boolean isPreloadAdvert) {
        if (adWrapper == null) {
            return;
        }
        if (isAdvertReady()) {
            onAdvertLoaded(false);
            return;
        }

        waitForAdvertToLoad(() -> {
            if (isAdvertReady()) {
                onAdvertLoaded(false);
                return;
            }
            if (adWrapper != null && fragmentActivity != null) {
                onAdvertRequestPre();

                adWrapper.loadAd(fragmentActivity, this);
            }
        });
    }

    private void showAdvert() {
        if (advertContainer == null || nativeSelfRender == null || !isAdvertReady()) {
            onAdvertShowFail();
            return;
        }

        final AbNativeAdWrapper realAdWrapper;
        if (adWrapper != null && adWrapper.isAdvertReady()) {
            realAdWrapper = adWrapper;
        } else {
            realAdWrapper = AbAdvertLoadManager.getInstance().getReadyNativeAdWrapper(advertConfig.getPlacementId());
        }
        if (realAdWrapper == null || !realAdWrapper.isAdvertReady()) {
            onAdvertShowFail();
            return;
        }

        this.realAdWrapper = realAdWrapper;
        realAdWrapper.showAd(advertContainer, this, nativeSelfRender);
    }

    private void onAdvertRequestPre() {
        if (advertCallback != null) {
            final ATAdInfoExt adInfoExt = new ATAdInfoExt();
            adInfoExt.adunit_id = advertConfig.getPlacementId();
            adInfoExt.adunit_format = AdUnitFormat.NATIVE.getValue();
            advertCallback.onAdvertRequestPre(this, adInfoExt);
        }
    }

    private void onAdvertRequestAlt() {
        if (advertCallback != null) {
            final ATAdInfoExt adInfoExt = new ATAdInfoExt();
            adInfoExt.adunit_id = advertConfig.getPlacementId();
            adInfoExt.adunit_format = AdUnitFormat.NATIVE.getValue();
            advertCallback.onAdvertRequestAlt(this, adInfoExt);
        }
    }

    private void onAdvertLoaded(boolean adLoadedReal) {
        if (adLoadedReal) {
            onAdvertRequestAlt();
        }
        if (advertCallback != null) {
            advertCallback.onAdvertLoaded(this);
        }
        if (advertConfig.isShowAfterLoaded()) {
            showAdvert();
        }
    }

    private void onAdvertShowFail() {
        if (advertCallback != null) {
            advertCallback.onAdvertShowFail(this);
        }
    }

    @Override
    public void onAdLoaded() {
        onAdvertLoaded(true);
    }

    @Override
    public void onAdFailedToLoad(@Nullable String loadAdError) {
        if (advertCallback != null) {
            advertCallback.onAdvertLoadFail(this, loadAdError);
        }
    }

    @Override
    public void onAdImpression(@Nullable ResponseInfo responseInfo) {
        if (advertCallback != null) {
            advertCallback.onAdvertShow(this, responseInfo);
        }
        if (advertConfig.isPreloadAdvert()) {
            final AbNativeAdvertConfig nativeAdvertConfig
                    = AdvertGsonUtils.getInstance().deepClone(advertConfig, AbNativeAdvertConfig.class);
            if (nativeAdvertConfig != null) {
                nativeAdvertConfig.setShowAfterLoaded(false);

                final AbNativeAdvert nativeAdvert = new AbNativeAdvert(lifecycleOwner, nativeAdvertConfig);
                nativeAdvert.loadAdvert(true);
            }
        }
    }

    @Override
    public void onAdDisplayFailed(@Nullable String adError) {
        onAdvertShowFail();
    }

    @Override
    public void onAdClicked(@Nullable ResponseInfo responseInfo) {
        if (advertCallback != null) {
            advertCallback.onAdvertClicked(this, responseInfo);
        }
    }

    @Override
    public void onAdClosed(@Nullable ResponseInfo responseInfo) {
        if (advertCallback != null) {
            advertCallback.onAdvertClose(this, responseInfo);
        }

        onAdvertRelease();
    }

    @Override
    public void onAdPaidEvent(@Nullable ResponseInfo responseInfo, @NonNull AdValue adValue) {
        if (advertCallback != null) {
            advertCallback.onAdvertRevenue(this, responseInfo, adValue);
        }
    }
}